﻿namespace SourceCodeRepository.Web.Tests.Controllers.Language
{
    using System.Linq;
    using System.Web.Mvc;
    using Helpers;
    using Model.Entitites;
    using System.Collections.Generic;
    using Moq;
    using Persistence.Repositories.Interfaces;
    using ViewDataTransformers;
    using Web.Controllers.Snippets;
    using Web.Views.ViewData;
    using Xunit;

    
    public class CreateSnippetControllerFacts
    {
        [Fact]
        public void Test_If_The_Controller_Can_Create_A_Snippet()
        {
            var mockedCodeSnippetRepository = new Mock<ICodeSnippetRepository>();
            var mockedContributorRepository = new Mock<IContributorRepository>();
            var mockedLanguageRepository = new Mock<ILanguageRepository>();
            var expectedLanguageId = 1;
            var expectedSnippetText = "Test";
            var expectedContributorId = 1;
            var expectedLanguage = new Language
            {
                Id = expectedLanguageId,
                Description = "Test"
            };
            var expectedContributor = new Contributor
            {
                Id = expectedContributorId,
                Name = "Test",
                EmailAddress = "test@test.com",
                Password = "Pass",
                UserName = "Test"
            };

            mockedLanguageRepository.Expect(o => o.GetById(expectedLanguageId)).Returns(expectedLanguage);
            mockedContributorRepository.Expect(o => o.GetById(expectedContributorId)).Returns(expectedContributor);

            var controller = new CreateSnippetController(mockedCodeSnippetRepository.Object, mockedLanguageRepository.Object, mockedContributorRepository.Object);
            controller.SetFakeControllerContext();
            controller.Request.Form["LanguageId"] = expectedLanguageId.ToString();
            controller.Request.Form["ContributorId"] = expectedContributorId.ToString();
            controller.Request.Form["SnippetText"] = expectedSnippetText;

            mockedCodeSnippetRepository.Expect(o => o.Save(It.IsAny<CodeSnippet>())).Verifiable();

            var viewResult = controller.CreateSnippet() as ViewResult;
            Assert.Equal(string.Empty, viewResult.ViewName);
            mockedCodeSnippetRepository.VerifyAll();
        }

        [Fact]
        public void Test_If_The_Controller_Can_ShowTheView()
        {
            var mockedCodeSnippetRepository = new Mock<ICodeSnippetRepository>();
            var mockedContributorRepository = new Mock<IContributorRepository>();
            var mockedLanguageRepository = new Mock<ILanguageRepository>();

            var expectedContributors = new List<Contributor>
                                           {
                                               new Contributor
                                                   {
                                                       EmailAddress = "test",
                                                       Id = 1,
                                                       Name = "test",
                                                       Password = "test",
                                                       UserName = "test"
                                                   },
                                               new Contributor
                                                   {
                                                       EmailAddress = "test",
                                                       Id = 2,
                                                       Name = "test",
                                                       Password = "test",
                                                       UserName = "test"
                                                   }
                                           };

            IList<Language> expectedLanguages = new List<Language>
                                        {
                                            new Language {Description = "C#", Id = 1},
                                            new Language {Description = "Java", Id = 2}
                                        };

            mockedContributorRepository.Expect(o => o.GetAllEntities()).Returns(expectedContributors);
            mockedLanguageRepository.Expect(o => o.GetAllEntities()).Returns(expectedLanguages);

            var controller = new CreateSnippetController(mockedCodeSnippetRepository.Object, mockedLanguageRepository.Object,
                                                         mockedContributorRepository.Object);
            var view = controller.ShowView() as ViewResult;

            Assert.IsType(typeof(CreateSnippetViewData), view.ViewData.Model);
            var viewData = view.ViewData.Model as CreateSnippetViewData;

            var languageTransformer = new LanguageViewDataTransformer();
            var contributorTransformer = new ContributorViewDataTransformer();

            var languageList = languageTransformer.Transform(expectedLanguages);
            var contributorList = contributorTransformer.Transform(expectedContributors);
            
            Assert.Equal(languageList.First(), viewData.Languages.First());
            Assert.Equal(languageList.Last(), viewData.Languages.Last());

            Assert.Equal(contributorList.First(), viewData.Contributors.First());
            Assert.Equal(contributorList.Last(), viewData.Contributors.Last());
        }
    }
}
